package logutil

import (
	"fmt"
	"io"
	"os"
	"path"
	"runtime"

	"github.com/natefinch/lumberjack"
	log "github.com/sirupsen/logrus"
)

const (
	// rollFileMaxSize is the maximum size in megabytes of the log file
	// before it gets rotated.
	rollFileMaxSize = 104857600

	// rollFileMaxBackups is the maximum number of old log files to retain.
	rollFileMaxBackups = 5

	// rollFileMaxAge is the maximum number of days to retain old log files.
	rollFileMaxAge = 30
)

// InitLog init log info.
func InitLog(logfile string, logLevel string) {
	// log.StandardLogger().Hooks.Add()
	dir := path.Dir(logfile)
	if dir != "." {
		os.Mkdir(dir, os.ModePerm)
	}

	// 1. set output files.
	setOutput(logfile)

	// 2. set log level, default indo level.
	setLogLevel(logLevel)

	// 3. set format, add file:line.
	log.SetFormatter(&log.TextFormatter{
		CallerPrettyfier: func(frame *runtime.Frame) (function string, file string) {
			return "", fmt.Sprintf("%s:%d", frame.File, frame.Line)
		},
	})
}

func setOutput(logfile string) {
	// set include the calling method as a field.
	log.SetReportCaller(true)

	// both stdout and log file.
	mw := io.MultiWriter(os.Stdout, &lumberjack.Logger{
		Filename:   logfile,
		MaxSize:    rollFileMaxSize,
		MaxBackups: rollFileMaxBackups,
		MaxAge:     rollFileMaxAge,
	})
	log.SetOutput(mw)
}

func setLogLevel(l string) {
	// default info level.
	if l == "" {
		log.SetLevel(log.InfoLevel)
		return
	}

	// set log level.
	level, err := log.ParseLevel(l)
	if err != nil {
		println("failed to parse log level, err:" + err.Error())
	}
	log.SetLevel(level)
}
